import { TimeManager } from './../common/timeManager';
import { isGeneratorFunctionName } from 'is-generator-function-name';
import { AbstractModel } from './../models/config';
import { LocalstorageDataManage } from './../common/localstoreage/localstoreageDataManage';
import { ProduceRecord } from './../models/produceRecord';
import { Observable } from 'rxjs';
import { InventoryProduceInfo } from './../models/inventoryProduceInfo';
import { businsessHttpServer } from './../common/http/http-server';
import { Repositoty, Reducer } from './repository';
import { FrontStoreStock, FrontStoreStockViewModel } from './../models/frontStoreStock';
import { httpResultCallback, parseUrl } from "../common/http/rest-api";
import { Inventory } from "./../models/inventory";
import * as R from "ramda";
import * as moment from 'moment';

//576c7bac98144542ab74cd6b328bef50

export class FrontStoreStocksService extends Repositoty<FrontStoreStockViewModel>{
    constructor() {
        let time = TimeManager.current.getNowTimeToBusinessTime();
        const initParseUrlOption  = LocalstorageDataManage.current.getValidSolution()?{ id: LocalstorageDataManage.current.getValidSolution().id, controller: "getFrontStoreStocks", query: { startTime: time.startTime, endTime: time.endTime } }:null;
        super("frontStoreStocks", initParseUrlOption, (state, action) => {
            switch (action.type) {
                case "seed":
                    return action.payload;
                case "change":
                    return state.map(entity =>
                        entity.id === action.payload.id ?
                            R.merge(entity, action.payload) :
                            entity
                    )
                case "augment":
                    return state.map(entity =>
                        entity.id === action.payload.id ?
                            { ...entity, localProductQuantity: entity.localProductQuantity + Number(action.payload.quantity) } :
                            entity
                    )
                default:
                    throw new Error("frontStoreStocks reducer default Error")
            }
        });
        (<any>window).frontStoreStocksService = this;
    }

    changeInitParseUrlOptionId(id: string) {
        const initParseUrlOption = this.getInitParseUrlOption();
        initParseUrlOption.id = id;
        this.setInitParseUrlOption(initParseUrlOption);
        this.reset();
    }

    private generateEmptyFrontStoreStock(inventory: Inventory): FrontStoreStockViewModel {
        const stack = <any>(new FrontStoreStock())
        stack.inventoryProduceInfo = new InventoryProduceInfo();
        stack.id = inventory.id;
        stack.inventoryId = inventory.id;
        stack.inventoryName = inventory.name;
        return stack;
    }

    async augmentFrontStoreStock(id: string, inventory: Inventory, quantity: number, producer: AbstractModel, beginTime: number, endTime: number) {
        const frontStoreStock = { id, inventoryId: inventory.id, quantity };
        const producerRecord = {
            producer,
            inventory,
            creator: producer,
            beginTime,
            endTime,
            terminal: LocalstorageDataManage.current.getTerminal()
        }
        const result = await this.put<FrontStoreStockViewModel>({ id, controller: "augmentFrontStoreStock", }, { frontStoreStock, producerRecord });
        this.disPatch({type:"augment",payload:{quantity,id}});
        this.changeEntity(result);
        return result;
    }

    empty(){
        this.disPatch({type:"seed",payload:[]})
    }

    async setSoldOutById(id) {
        const result = await this.put<FrontStoreStockViewModel>({ id, controller: "setSoldOut", }, {});
        this.changeEntity(result);
        return result;
    }

    async cancelSoldOutById(id) {
        const result = await this.put<FrontStoreStockViewModel[]>({ id:"cancelSoldOut"}, {frontStoreStockIds:[id]});
        this.changeEntities(result);
        return result;
    }

    async getScrapOutStocks() {
        let endTime = new Date().getTime();
        let startTime = moment().startOf('day').subtract(3, 'days').valueOf();
        return await httpResultCallback(businsessHttpServer(parseUrl(`/api/scrapOutFrontStoreStocks`, {
            controller: "getScrapOutStocks", query: {
                startTime: startTime,
                endTime: endTime
            }
        })).get());
    }

    async setScrapOut(creator, scrapOuts: Array<{ frontStoreStockId: string, quantity: number, inventory: Inventory }>) {
        const result = await httpResultCallback<{ frontStoreStocks: Array<FrontStoreStock> }>(businsessHttpServer(parseUrl(`/api/scrapOutFrontStoreStocks`, {
            controller: "setScrapOut"
        })).post({
            creator, frontStoreStocks: scrapOuts.map(scrapOut => {
                (<any>scrapOut).id = scrapOut.frontStoreStockId;
                return scrapOut;
            })
        }));
        this.changeEntity(<any>result.frontStoreStocks[0])
        return result;
    }

    async getChefKitchenSolutions() {
        return await httpResultCallback<Array<any>>(businsessHttpServer(parseUrl(`/api/kitchensolutions`, {
            query: {
                media: "kp"
            }
        })).get());
    }
}